package com.matthicks.macrobot;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.UnknownHostException;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;

public class ScreenSelector {
	public static final String HOST = "pickler.imirus.local";
//	public static final String HOST = "192.168.42.128";
	
	public BufferedImage image;
	
	public ScreenSelector() throws UnknownHostException, IOException {
		RemoteController rc = new RemoteController(HOST, 2600);
		try {
			image = rc.screenshot();
			ImageIcon icon = new ImageIcon(image);
			JFrame frame = new JFrame("Screenshot");
			frame.setResizable(false);
			frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			
			JPanel panel = new JPanel();
			panel.setLayout(new OverlayLayout(panel));
			frame.setContentPane(panel);
			
			SelectionComponent sc = new SelectionComponent(this);
			panel.add(sc);
			
			JLabel label = new JLabel(icon);
			panel.add(label);
			
			frame.addKeyListener(sc);
			frame.pack();
			frame.setVisible(true);
		} finally {
			rc.disconnect();
		}
	}
	
	public void export(int x, int y, int width, int height) {
		String filename = JOptionPane.showInputDialog("Please enter the filename (exclude extension):");
		try {
			RemoteController rc = new RemoteController(HOST, 2600);
			try {
				rc.screensave(x, y, width, height, filename + ".png");
				System.out.println("Saved: " + filename + ".png at " + x + "x" + y + " with a size of: " + width + "x" + height);
			} finally {
				rc.disconnect();
			}
		} catch(Throwable t) {
			t.printStackTrace();
		}
		System.exit(0);
	}
	
	public static void main(String[] args) throws Exception {
		new ScreenSelector();
	}
}

class SelectionComponent extends JComponent implements KeyListener, MouseListener, MouseMotionListener {
	private static final long serialVersionUID = -1326013393855160924L;
	
	private ScreenSelector s;
	
	private int x = 0;
	private int y = 0;
	private int width = 0;
	private int height = 0;
	
	public SelectionComponent(ScreenSelector s) {
		this.s = s;
		
		setOpaque(false);
		
		addMouseListener(this);
		addMouseMotionListener(this);
	}

	public void paint(Graphics g) {
		super.paint(g);
		
		g.setColor(new Color(0.0f, 0.0f, 0.0f, 0.5f));
		
		if ((Width() > 0) && (Height() > 0)) {
			if (X() > 0) {
				g.fillRect(0, Y(), X(), getHeight() - Y());
			}
			if (Y() > 0) {
				g.fillRect(0, 0, getWidth(), Y());
			}
			if (Width() < getWidth()) {
				g.fillRect(X() + Width(), Y(), getWidth() - (X() + Width()), getHeight()); 
			}
			if (Height() < getHeight()) {
				g.fillRect(X(), Y() + Height(), Width(), getHeight() - (Y() + Height()));
			}
		}
//		System.out.println("DRAWING! " + X() + "x" + Y() + " - " + Width() + "x" + Height());
	}
	
	public int X() {
		if (width < 0) {
			return x + width;
		}
		return x;
	}
	
	public int Y() {
		if (height < 0) {
			return y + height;
		}
		return y;
	}
	
	public int Width() {
		return Math.abs(width);
	}
	
	public int Height() {
		return Math.abs(height);
	}
	
	private void updateValues() {
		int x = X();
		int y = Y();
		int w = Width();
		int h = Height();
		
		this.x = x;
		this.y = y;
		this.width = w;
		this.height = h;
	}

	public void mouseClicked(MouseEvent evt) {
	}

	public void mouseEntered(MouseEvent evt) {
	}

	public void mouseExited(MouseEvent evt) {
	}

	public void mousePressed(MouseEvent evt) {
		x = evt.getX();
		y = evt.getY();
		width = 0;
		height = 0;
		repaint();
	}

	public void mouseReleased(MouseEvent evt) {
	}

	public void mouseDragged(MouseEvent evt) {
		width = evt.getX() - x;
		height = evt.getY() - y;
		repaint();
	}

	public void mouseMoved(MouseEvent evt) {
	}

	public void keyPressed(KeyEvent evt) {
		if (evt.getKeyCode() == KeyEvent.VK_LEFT) {
			updateValues();
			if (x > 0) {
				x--;
				if (evt.isShiftDown()) {
					width++;
				} else if (evt.isControlDown()) {
					x++;
					if (width > 0) width--;
				}
				repaint();
			}
		} else if (evt.getKeyCode() == KeyEvent.VK_UP) {
			updateValues();
			if (y > 0) {
				y--;
				if (evt.isShiftDown()) {
					height++;
				} else if (evt.isControlDown()) {
					y++;
					if (height > 0) height--;
				}
				repaint();
			}
		} else if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
			updateValues();
			if (x + width < getWidth()) {
				if (evt.isShiftDown()) {
					width++;
				} else if (evt.isControlDown()) {
					x++;
					width--;
				} else {
					x++;
				}
				repaint();
			}
		} else if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
			updateValues();
			if (y + height < getHeight()) {
				if (evt.isShiftDown()) {
					height++;
				} else if (evt.isControlDown()) {
					y++;
					height--;
				} else {
					y++;
				}
				repaint();
			}
		} else if (evt.getKeyCode() == KeyEvent.VK_X) {
			s.export(X(), Y(), Width(), Height());
		}
	}

	public void keyReleased(KeyEvent evt) {
	}

	public void keyTyped(KeyEvent evt) {
	}
}